/* 
 * Copyright 2011 QDSS.org. All rights reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.qdss.oapi4j.base;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

/**
 * JSON结果集
 * 
 * @author <a href="mailto:zhaofang123@gmail.com">Zhao Fangfang</a>
 * @date 2011-3-20
 * @version $Id: JsonResult.java 20 2011-04-11 15:38:23Z zhaofang123@gmail.com $
 */
public class JsonResult extends BaseResult<JSONObject> {

	private JSONObject rootObject;
	
	/**
	 * @param result
	 * @param invokeTime
	 * @param headers
	 */
	public JsonResult(String result, int invokeTime, Header[] headers) {
		super(result, invokeTime, headers);
	}
	
	public JSONObject rootValue() {
		if (rootObject == null) {
			try {
				rootObject = JSONObject.parseObject(getRawResult());
			} catch (JSONException ex) {
				throw new BadResultException("Bad JSON result: " + getRawResult());
			}
		}
		return rootObject;
	}
	
	public JSONObject nodeValue(String path) {
		String paths[] = splitPaths(path);
		JSONObject o = getNodeValueWithoutLast(paths);
		return o.getJSONObject(paths[paths.length - 1]);
	}
	
	public boolean hasValue(String path) {
		return nodeValue(path) != null;
	}
	
	public String getStringValue(String path) {
		String paths[] = splitPaths(path);
		JSONObject o = getNodeValueWithoutLast(paths);
		String s = o.getString(paths[paths.length - 1]);
		if (s == null) {
			throw new NoMatchValueException("No value in path: " + path);
		}
		return s;
	}

	public Integer getIntValue(String path) {
		String paths[] = splitPaths(path);
		JSONObject o = getNodeValueWithoutLast(paths);
		Integer s = o.getInteger(paths[paths.length - 1]);
		if (s == null) {
			throw new NoMatchValueException("No value in path: " + path);
		}
		return s;
	}

	public Long getLongValue(String path) {
		String paths[] = splitPaths(path);
		JSONObject o = getNodeValueWithoutLast(paths);
		Long s = o.getLong(paths[paths.length - 1]);
		if (s == null) {
			throw new NoMatchValueException("No value in path: " + path);
		}
		return s;
	}
	
	public Double getDoubleValue(String path) {
		String paths[] = splitPaths(path);
		JSONObject o = getNodeValueWithoutLast(paths);
		Double s = o.getDouble(paths[paths.length - 1]);
		if (s == null) {
			throw new NoMatchValueException("No value in path: " + path);
		}
		return s;
	}

	/**
	 * 分割路径，分隔符支持'.'或'/'
	 * 
	 * @param path
	 * @return
	 */
	protected String[] splitPaths(String path) {
		if (path.contains(".")) {
			path = path.replaceAll("\\.", "\\/");
		}
		return path.split("\\/");
	}
	
	/**
	 * @param paths
	 * @return
	 */
	protected JSONObject getNodeValueWithoutLast(String[] paths) {
		JSONObject o = rootValue();
		for (int i = 0; i < paths.length - 1; i++) {
			// 空节点不处理而非抛出异常，是为了与XML路径保持兼容
			if (!StringUtils.isBlank(paths[i])) {
				o = o.getJSONObject(paths[i]);
			}
		}
		return o;
	}
	
	public String getError() {
		throw new UnsupportedOperationException();
	}
	
	public boolean hasError() {
		throw new UnsupportedOperationException();
	}
}
